/* *****************************************************************************
 * JFab (http://code.google.com/p/jfab)
 * Copyright (c) 2011 JFab.org
 * Admin jfab@jeffreythompson.net
 *
 * See the file "LICENSE.txt" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 * *****************************************************************************/

package org.jfab.core.io;

import java.io.Writer;

import org.apache.commons.lang3.Validate;
import org.jfab.core.collection.CGAnnotationList;
import org.jfab.core.collection.CommentList;
import org.jfab.core.collection.ModifierList;
import org.jfab.core.factory.StringFactory;
import org.jfab.core.factory.TypeReferenceSupport;
import org.jfab.core.model.CGField;

/**
 * Provides a field writer.
 */
public final class CGFieldWriter implements CGWriter<CGField>
{
    /** Basic code generator. */
    private final BasicCodeGenerator _basicCodeGenerator;

    /** String factory. */
    private final StringFactory _stringFactory;

    /** Type reference support. */
    private final TypeReferenceSupport _typeReferenceSupport;

    /**
     * Construct this object with the given parameters.
     * 
     * @param typeReferenceSupport Type reference support.
     * @param stringFactory String factory.
     * @param basicCodeGenerator Basic code generator.
     */
    public CGFieldWriter(final TypeReferenceSupport typeReferenceSupport,
            final StringFactory stringFactory,
            final BasicCodeGenerator basicCodeGenerator)
    {
        _typeReferenceSupport = typeReferenceSupport;
        _stringFactory = stringFactory;
        _basicCodeGenerator = basicCodeGenerator;
    }

    /**
     * Write a field.
     * 
     * @param writer Writer.
     * @param field Field.
     */
    @Override
    public final void write(final Writer writer, final CGField field)
    {
        Validate.notNull(field, "field is null");

        final StringFactory stringFactory = getStringFactory();

        final CommentList commentLines = new CommentList(
                field.getCommentLines());
        final String annotationsString = stringFactory
                .createAnnotationsString(new CGAnnotationList(field
                        .getAnnotations()));
        final String modifiersString = stringFactory
                .createModifiersString(new ModifierList(field.getModifiers()));
        final String typeString = getTypeReferenceSupport().createTypeString(
                field.getType());
        final String fieldName = field.getName();
        final String initialValueString = stringFactory
                .createInitialValueString(field.getInitialValue());

        if (commentLines.size() == 1)
        {
            getBasicCodeGenerator().writeSingleLineJavadocComment(writer,
                    commentLines.get(0));
        }
        else
        {
            getBasicCodeGenerator().writeMultilineJavadocComment(writer,
                    commentLines);
        }

        getBasicCodeGenerator().writeLine(
                writer,
                annotationsString + modifiersString + typeString + " "
                        + fieldName + initialValueString + ";");
    }

    /**
     * @return the basicCodeGenerator
     */
    private BasicCodeGenerator getBasicCodeGenerator()
    {
        return _basicCodeGenerator;
    }

    /**
     * @return the stringFactory
     */
    private StringFactory getStringFactory()
    {
        return _stringFactory;
    }

    /**
     * @return the typeReferenceSupport
     */
    private TypeReferenceSupport getTypeReferenceSupport()
    {
        return _typeReferenceSupport;
    }
}
